package model;

import javax.swing.text.Document;

import view.AnwerChecker;

import model.Batch.BatchType;
import model.Lesson.RepeatMode;
import eventHandling.EventBus;
import eventHandling.EventTyp.Type;

/**
 * The LessonGuide manages the current state of the application.
 * 
 * @author sloth42
 *
 */
public class LessonGuide {

	private Card currentCard;
	private Lesson currentLesson;
	private EventBus eventBus;
	private AnwerChecker myAnwerChecker;
	private int ultraShortTimeMemoryTime = 18;
	private int shortTimeMemoryTime = 120;

	public LessonGuide(EventBus eventBus) {
		this.eventBus = eventBus;
	}

	/**
	 * Returns the number of all Cards in this Lesson
	 * 
	 * @return
	 */
	public int getNumberOfCards() {

		int numOfCards = 0;

		// Not Lerned
		numOfCards += currentLesson.getNotLearnedBatch().getNumberOfCards();

		// Ultra Short Time
		numOfCards += currentLesson.getUltraShortTimeBatch().getNumberOfCards();

		// short Time
		numOfCards += currentLesson.getShortTimeBatch().getNumberOfCards();

		// Long Term
		for (Batch batch : currentLesson.getAllLongTermBatches()) {
			numOfCards += batch.getNumberOfCards();
		}

		return numOfCards;
	}

	public int getNumberOfBatches() {
		return currentLesson.getAllLongTermBatches().size();
	}

	public int getNumberOfCards(int longTermBatchNumber) {
		return currentLesson.getLongTermBatch(longTermBatchNumber)
				.getNumberOfCards();
	}

	/**
	 * Returns the number of cards in batch. But only for NOT_LEARNDED,
	 * ULTRA_SHORT_TIME_MEMORY and SHORT_TIME_MEMORY batches. To get the number
	 * of cards in a LONG_TERM batch use <i>getNumberOfCards(int
	 * longTermBatchNumber)</i>
	 * Cards
	 * @param batchType
	 * @return number of cards in a batch
	 */
	public int getNumbersOfCards(BatchType batchType) {
		if (batchType == BatchType.NOT_LEARNED) {
			return currentLesson.getNotLearnedBatch().getNumberOfCards();
		} else if (batchType == BatchType.ULTRA_SHORT_TIME_MEMORY) {
			return currentLesson.getUltraShortTimeBatch().getNumberOfCards();
		} else if (batchType == BatchType.SHORT_TIME_MEMORY) {
			return currentLesson.getShortTimeBatch().getNumberOfCards();
		}

		return -1;
	}

	/**
	 * Returns the number of expired Cards in a long term batch
	 * 
	 * @param batchNumber
	 * @return number of expired Cards
	 */
	public int getNumberOfExpiredCards(int batchNumber) {

		Batch tempBatch = currentLesson.getLongTermBatch(batchNumber);

		int numOfExpiredCards = 0;

		for (Card card : tempBatch.getCards()) {
			if (card.getExpiredTime() < System.currentTimeMillis()) {
				++numOfExpiredCards;
			}
		}

		return numOfExpiredCards;
	}

	/**
	 * Returns the number of all expired cards in the lesson
	 * 
	 * @return number of expired cards
	 */
	public int getNumberOfExpiredCards() {
		int numOfExpiredCards = 0;

		//There are only expired cards in long term batches
		for (int batchNo = 0; batchNo < currentLesson.getAllLongTermBatches()
				.size(); batchNo++) {
			numOfExpiredCards += getNumberOfExpiredCards(batchNo++);
		}

		return numOfExpiredCards;
	}

	public void createNewCard(Document frontSide, Document reverseSide) {

		// tell the eventbus that at least one Card is in the "not learned" -
		// batch
		if (currentLesson.getNotLearnedBatch().getNumberOfCards() == 0) {
			eventBus.fireEvent(Type.NOT_LEARNED_CARDS_AVAILABLE);
		}

		currentLesson.getNotLearnedBatch().addCard(
				new Card(frontSide, reverseSide));
	}

	public Card getCurrentCard() {
		return currentCard;
	}

	public void setCurrentCard(Card currentCard) {
		this.currentCard = currentCard;
	}

	public Lesson getCurrentLesson() {
		return currentLesson;
	}

	public void setCurrentLesson(Lesson currentLesson) {
		this.currentLesson = currentLesson;
	}

	public void createNewLesson(RepeatMode repeatModeIndex,
			boolean onlyVocabularySelected, String description) {

		currentLesson = new Lesson(repeatModeIndex, onlyVocabularySelected,
				description);
		eventBus.fireEvent(Type.LESSON_CREATED);

	}

	/**
	 * Get the number of unlearned cards in a batch. 
	 * @param batchNumber
	 * @return number of unlearned cards
	 */
	public int getNumberOfUnLearnedCards(int batchNumber) {
		
		Batch tempBatch = currentLesson.getLongTermBatch(batchNumber);

		int numOfUnLearnedCards = 0;

		for (Card card : tempBatch.getCards()) {
			if (card.getExpiredTime() == -1) {
				++numOfUnLearnedCards;
			}
		}

		return numOfUnLearnedCards;
		
	}
	
	/**
	 * Returns the number of all unlearned cards in this lesson.
	 * @return
	 */
	public int getNumberOfUnLearnedCards() {

		return  currentLesson.getNotLearnedBatch().getNumberOfCards();
		
	}

	public int getNumberOfLearnedCards() {
		// TODO Auto-generated method stub
		return 0;
	}

	public int getUltraShortTimeMemoryTime() {
		return ultraShortTimeMemoryTime;
	}

	public void setUltraShortTimeMemoryTime(int ultraShortTimeMemoryTime) {
		this.ultraShortTimeMemoryTime = ultraShortTimeMemoryTime;
	}

	/**
	 * Returns how long the short-time-memory should be trained in seconds.
	 * @return time in seconds
	 */
	public int getShortTimeMemoryTime() {
		return shortTimeMemoryTime;
	}

	/**
	 * Returns how long the ultra-short-time-memory should be trained in seconds.
	 * @return time in seconds
	 */
	public void setShortTimeMemoryTime(int shortTimeMemoryTime) {
		this.shortTimeMemoryTime = shortTimeMemoryTime;
	}
	
}